package com.yihong.common.util;

import com.google.gson.Gson;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName JwtUtil
 * @Description 使用场景:一种情况是webapi,另一种情况是多web服务器下实现无状态分布式身份验证。 JWT是JSON Web Token的缩写，
 * 即JSON Web令牌。JSON Web令牌（JWT）是一种紧凑的、URL安全的方式， 用来表示要在双方之间传递的“声明”。
 * JWT中的声明被编码为JSON对象，用作JSON Web签名（JWS）结构的有效内容或JSON Web加密（JWE）结构的明文，
 * 使得声明能够被：数字签名、 或利用消息认证码（MAC）保护完整性、加密。
 * @Author 孟志浩
 * @Date 2019/3/19 10:19
 **/
public class JwtUtil {

    static final String KEY = "2381tht93hgf1gfrhofh193hg8130h9gf3";

    // 过期时间 30分钟
    private static final long EXPIRATION = 3600L;

    private static final String CT = "createTime";

    // 过期时间 7天
    private static final long EXPIRATION_REMEMBER = 604800000L;

    /**
     * 解密,并验证是否过期
     * @param jsonWebToken
     * @return 正确解密并且未过期则返回Claims，否则返回null
     */
    public static Claims parseJWT(String jsonWebToken) {
        if (jsonWebToken == null || jsonWebToken.trim().equals("")) {
            return null;
        }
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(KEY.getBytes())
                    .parseClaimsJws(jsonWebToken)
                    .getBody();
            if (System.currentTimeMillis() - ((Long)claims.get(CT)) < EXPIRATION_REMEMBER) {
                return claims;
            }
            return null;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
      * 创建一个token
      * @param map         token中存放的信息，不能过多userId、和角色即可
      * @return java.lang.String
      * @author 孟志浩
      * @date 2019/3/19
      **/
    public static String createJWT(Map<String, Object> map) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS512;
        if (map == null || map.size() == 0) {
            throw new IllegalArgumentException("生成token至少应该有一个有效参数");
        }
        map.put(CT, new Date());
        //添加构成JWT的参数
        JwtBuilder builder = Jwts
                .builder()
                .setHeaderParam("typ", "JWT")
                .setClaims(map)
                .signWith(signatureAlgorithm, KEY.getBytes());
        return builder.compact();
    }

    /**
      * 秘钥是否有效,有效期7天
      * @param token
      * @return boolean
      * @author 孟志浩
      * @date 2019/3/19
      **/
    public static boolean isPass(String token){
        Claims claims = parseJWT(token);
        if (claims == null) {
            return false;
        }
        return System.currentTimeMillis() - ((Long)parseJWT(token).get(CT)) < EXPIRATION_REMEMBER;
    }

    public static long getUserId(String token)
    {
        Claims claims = parseJWT(token);
        return Long.valueOf(String.valueOf(claims.get("userId")));
    }

    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("userId", "121546");
        String jwt = createJWT(map);
        System.out.println(jwt);
        System.out.println(isPass(jwt));
    }

}
